iT邦幫忙

2023 iThome 鐵人賽

DAY 11
0
Software Development

掌握Java神器,駕馭SpringBoot猛獸系列 第 11

第十一日 從荷包蛋看依賴性注入

  • 分享至 

  • xImage
  •  

前兩日說到了軟體設計的準則,今天配合實際案例說明架構設計原則

關於設計原則

合成複用原則(Composition Over Inheritance)
軟體設計核心概念除了SOLID原則原則外,還有一個合成復用原則,旨在強調類別間的依賴關係應該避免繼承,而是盡量用組合方式將類別擴充新功能,試想當一個類別的方法出現太多判斷式,或是行數接近千行,這時候適當的處理方式就是拆分模組或是工具類,放入原有的方法實作中來完成邏輯

依賴性注入(Dependency Inject)
與合成複用原則類似實作概念為依賴性注入,這個手法存在的目的就是由外部來改變類別依賴的模組,是昨日提到的依賴反轉原則,具體實現概念,現在透過範例來說明依賴性注入

用實際例子說明原理

先來透過程式定義主角-喜歡吃荷包蛋的布偶貓

class CrazyPuppetCat {
    // 打印喜歡的食物
    public void favorateFood() {
        System.out.println("喜歡瘋狂吃荷包蛋");
    }
}

有一天布偶貓肚子餓了想要吃荷包蛋,於是打電話請烏龜好朋友外送,這時候程式碼會改動成這樣...

// 烏龜
class Turtle {
    private String food = "荷包蛋";
    private String name = "烏龜";

    public String getName() {
        return name;
    }

    // 打印發送的食物
    public String givenFood() {
        return food;
    }
}

class CrazyPuppetCat {
    // 烏龜外送員
    private Turtle foodSender = new Turtle;

    public void getFood() {
        String senderName = foodSender.getName();
        String food = foodSender.givenFood();
        System.out.printf(
                "布偶貓從 %s 手中拿到宵夜 %s\n",
                senderName, food);
    }
}

接著用瘋狂布偶貓的實體化物件執行 getFood 方法,打印出布偶貓透過依賴的烏龜實例,取得宵夜的文字

不同依賴對象可能遇到的問題

那麼問題來了,當瘋狂的布偶貓想要找貓頭鷹、鴨子來送荷包蛋,每次就要修改 foodSender屬性,這個動作違反了開放封閉原則,以及依賴反轉原則,為了解決這個問題必須將程式碼進行改寫

來個 Interface 規範外送員要有的行為

   interface FoodSender {
        String givenFood();

        String getName();
    }

在建立其他動物類別

// 貓頭鷹類別
class Owl implements FoodSender {
    private String food = "荷包蛋";
    private String name = "貓頭鷹";

    @Override
    public String getName() {
        return name;
    }

    // 打印發送的食物
    @Override
    public String givenFood() {
        return food;
    }
}

// 鴨子類別
class Duck implements FoodSender {
    private String food = "荷包蛋";
    private String name = "鴨子";

    @Override
    public String getName() {
        return name;
    }

    // 打印發送的食物
    @Override
    public String givenFood() {
        return food;
    }
}

布偶貓類別的外送員屬性調整參考型別,並建立新方法設定依賴的外送員

// CrazyPuppetCat.java

    // 將屬性修改成外送員介面
    private FoodSender foodSender; // 外送員

    // 新增設定外送員的方法
    public void setFoodSend(FoodSender _foodSender) {
        foodSender = _foodSender;
    }

// 在 main方法 實際運行程式碼看輸出
public static void main(String[] args){
    CrazyPuppetCat cat = new CrazyPuppetCat();
    cat.setFoodSend(new Turtle());
    cat.getFood(); // 布偶貓從 烏龜手中拿到消夜 荷包蛋

    cat.setFoodSend(new Duck());
    cat.getFood(); // 布偶貓從 鴨子 手中拿到宵夜 荷包蛋

    cat.setFoodSend(new Owl());
    cat.getFood(); // 布偶貓從 貓頭鷹 手中拿到宵夜 荷包蛋
}

從測試結果可以發現調整後的做法能做到,不修改布偶貓類別的情況下將依賴的外送員替掉,這個手法叫做「依賴性注入」,利用各種方式變更使用到的實例物件,常見作法有透過建構子、方法(同範例)以及控制反轉(IOC)容器注入實體的容器,Spring Boot則是利用了IOC容器,實現依賴性注入


上一篇
第十日 談SOLID原則
下一篇
第十二日 看代理模式
系列文
掌握Java神器,駕馭SpringBoot猛獸30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言